package com.frikinet.lifeguard.gui.dialogs;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.SortedSet;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.SwingWorker;

import com.frikinet.lifeguard.App;
import com.frikinet.lifeguard.fotolog.FotologDataLoader;
import com.frikinet.lifeguard.fotolog.FotologException;
import com.frikinet.lifeguard.fotolog.FotologLoaderListener;
import com.frikinet.lifeguard.fotolog.FotologUnexpectedException;
import com.frikinet.lifeguard.model.Post;
import com.frikinet.tools.gui.ActionHandler;
import com.frikinet.tools.gui.FButton;

public class FotologLoadingDataDialog extends JDialog
{
	private static final long serialVersionUID = 1L;
	
	private ActionHandler handler = new ActionHandler(this);
	
	private JTextField userName;
	private JProgressBar progress;
	private JLabel status;
	private Task task;
	private JButton start, accept;
	
	public FotologLoadingDataDialog(JDialog parent, String userName)
	{
		super(parent);
		
		commonConstructor(parent, userName);
	}
	
	public FotologLoadingDataDialog(JFrame parent, String userName)
	{
		super(parent);
		
		commonConstructor(parent, userName);
	}
	
	private void commonConstructor(Component parent, String userName)
	{
		this.userName = new JTextField(userName);
		this.userName.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e)
			{
				if(e.getKeyCode()==KeyEvent.VK_ENTER)
				{
					action_start();
				}
			}
		});
		
		setTitle(App.i18n.translate("dialog.loader.title"));
		setModal(true);
		
		buildGUI();
		
		
		pack();
		setLocationRelativeTo(parent);
		setVisible(true);
	}
	
	public void buildGUI()
	{
		JPanel contentPane = new JPanel(new BorderLayout());
		contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		
		JPanel north = new JPanel(new BorderLayout());
		north.add(new JLabel(App.i18n.translate("dialog.loader.labels.user")+":"), BorderLayout.WEST);
		north.add(userName, BorderLayout.CENTER);
		start = createButton("start");
		north.add(start, BorderLayout.EAST);
		contentPane.add(north, BorderLayout.NORTH);
		
		JPanel center = new JPanel(new BorderLayout());
		progress = new JProgressBar();
		progress.setStringPainted(false);
		progress.setPreferredSize(new Dimension(400, 30));
		center.add(progress, BorderLayout.CENTER);
		status = new JLabel(" ");
		center.add(status, BorderLayout.SOUTH);
		contentPane.add(center, BorderLayout.CENTER);
		
		JPanel south = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		accept = createButton("accept");
		south.add(accept);
		contentPane.add(south, BorderLayout.SOUTH);
		
		setContentPane(contentPane);
	}
	
	private JButton createButton(String name)
	{
		FButton button = new FButton(String.format("dialog.loader.buttons.%s", name));
		button.setI18N(App.i18n);
		button.setActionCommand(name);
		button.addActionListener(handler);
		button.translate();
		return button;
	}
	
	public void action_start()
	{
		if(userName.getText().equals(""))
		{
			JOptionPane.showMessageDialog(this, App.i18n.translate("dialog.loader.errors.blank.text"), "", JOptionPane.ERROR_MESSAGE);
		}
		else
		{
			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
			start.setEnabled(false);
			accept.setEnabled(false);
			userName.setEnabled(false);
			task = new Task();
			task.execute();
		}
	}
	
	public void action_accept()
	{
		dispose();
	}
	
	public void loadFinish()
	{
		setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		start.setEnabled(true);
		accept.setEnabled(true);
		userName.setEnabled(true);
	}
	
	public class Task extends SwingWorker<Void, Void> implements FotologLoaderListener
	{
		JProgressBar progress = FotologLoadingDataDialog.this.progress;
		JLabel status = FotologLoadingDataDialog.this.status;
		
		int posts = 0, totalPosts = 0;
		
		@Override
		protected Void doInBackground() throws Exception
		{
			try
			{
				FotologDataLoader loader = new FotologDataLoader(FotologLoadingDataDialog.this.userName.getText());
				loader.addLoaderListener(this);
				loader.loadData();
				App.events.fireModelChanged();
			}
			catch(FotologException e)
			{
				JOptionPane.showMessageDialog(FotologLoadingDataDialog.this, e.getMessage(), App.i18n.translate("dialog.loader.errors.loading.title"), JOptionPane.ERROR_MESSAGE);
			}
			catch(FotologUnexpectedException e)
			{
				JOptionPane.showMessageDialog(FotologLoadingDataDialog.this, e.getCause().getMessage(), App.i18n.translate("dialog.loader.errors.loading.title"), JOptionPane.ERROR_MESSAGE);
			}
			return null;
		}
		
		@Override
		protected void done()
		{
			FotologLoadingDataDialog.this.loadFinish();
		}

		@Override
		public void loadStarted()
		{
			progress.setIndeterminate(true);
			status.setText(App.i18n.translate("dialog.loader.msg.loading.init"));
		}

		@Override
		public void yearsCalculated(SortedSet<Integer> years)
		{
			progress.setIndeterminate(false);
			progress.setStringPainted(true);
			progress.setMinimum(0);
			progress.setMaximum(years.size() * 12);
			progress.setValue(0);
			status.setText(App.i18n.translate("dialog.loader.msg.loading.years", years.size()));
		}

		@Override
		public void readingMonth(int month, int year)
		{
			progress.setValue(progress.getValue() + 1);
			status.setText(App.i18n.translate("dialog.loader.msg.loading.post.read", month, year, totalPosts));
		}

		@Override
		public void postFound(Post post)
		{
			totalPosts++;
		}

		@Override
		public void postLookupFinished(List<Post> posts)
		{
			progress.setMinimum(0);
			progress.setMaximum(posts.size());
			progress.setValue(0);
			status.setText(App.i18n.translate("dialog.loader.msg.loading.lookup"));
		}

		@Override
		public void postProcessed(Post post)
		{
			progress.setValue(progress.getValue() + 1);
			status.setText(App.i18n.translate("dialog.loader.msg.loading.post.loaded", post.getDate(), ++posts, totalPosts));
		}

		@Override
		public void loadEnded()
		{
			status.setText(App.i18n.translate("dialog.loader.msg.loading.end"));
		}
	}
}
